/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.gen2phen.labs.services;

import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import org.gen2phen.labs.domain.Investigation;
import org.gen2phen.labs.domain.ObservableFeature;

/**
 *
 * @author pedrolopes
 *
 * GEN2PHEN Semantic Web Labs: Knowledge Mashup
 *
 */
public class Loader {

    private static ArrayList<Investigation> invs = new ArrayList<Investigation>();
    private static ArrayList<ObservableFeature> feats = new ArrayList<ObservableFeature>();

    /*
     * Loads all investigations from the Pheno-OM database using the D2R SPARQL endpoint
     */
    public static boolean load() {
        boolean success = false;

        try {
            HashMap<String, Investigation> invests = new HashMap<String, Investigation>();

            String service = "http://localhost:2020/sparql";    // default location of the D2R SPARQL endpoint

            // start loading all investigations
            String sparqlInvs =
                    "PREFIX dc: <http://purl.org/dc/elements/1.1/>"
                    + "PREFIX foaf: <http://xmlns.com/foaf/0.1/>"
                    + "PREFIX d2rq: <http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#>"
                    + "PREFIX map: <file:///stdout#>"
                    + "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"
                    + "PREFIX vocab: <http://localhost:2020/vocab/resource/>"
                    + "SELECT ?name ?desc WHERE {"
                    + " ?inv vocab:investigation_name ?name ."
                    + " ?inv vocab:investigation_description ?desc ."
                    + "}";

            QueryExecution e = QueryExecutionFactory.sparqlService(service, sparqlInvs);

            ResultSet rs = e.execSelect();

            while (rs.hasNext()) {
                QuerySolution row = rs.nextSolution();

                // add investigation to local HashMap
                invests.put(row.getLiteral("name").toString(), new Investigation(row.getLiteral("name").toString(), row.getLiteral("desc").toString()));

            }

            // start loading all observable features
            String sparqlFeats =
                    "PREFIX dc: <http://purl.org/dc/elements/1.1/>"
                    + "PREFIX foaf: <http://xmlns.com/foaf/0.1/>"
                    + "PREFIX d2rq: <http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#>"
                    + "PREFIX map: <file:///stdout#>"
                    + "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"
                    + "PREFIX vocab: <http://localhost:2020/vocab/resource/>"
                    + "SELECT ?obsname ?desc ?invname WHERE {"
                    + "?inv vocab:investigation_name ?invname ."
                    + " ?obs vocab:observablefeature_investigation ?inv ."
                    + " ?obs vocab:observablefeature_name ?obsname ."
                    + "}";
            QueryExecution eF = QueryExecutionFactory.sparqlService(service, sparqlFeats);
            ResultSet rsF = eF.execSelect();
            while (rsF.hasNext()) {
                QuerySolution row = rsF.nextSolution();

                // normalize results
                String[] obs = row.getLiteral("obsname").toString().split(" - ");
                String obsname = obs[0];
                String invname = row.getLiteral("invname").toString();

                // get Observable Feature associated investigation from local HashMap
                Investigation inv = invests.get(invname);

                ObservableFeature feat = new ObservableFeature(obsname, inv);

                try {
                    feats.add(feat);    // add loaded feature to global features array list
                    inv.addFeature(feat);   // addd loaded feature to associated investigation

                } catch (Exception ex) {
                    System.out.println("Failure with feature " + feat.getName());
                }
            }

            for (Investigation i : invests.values()) {
                invs.add(i);    // load all investigation from HashMap to global ArrayList
            }
            success = true;
        } catch (Exception ex) {
            System.out.println("Unable to load data..." + ex.toString());
        }
        return success;

    }

    public static ArrayList<Investigation> investigations() {
        return invs;
    }

    public static ArrayList<ObservableFeature> feature() {
        return feats;
    }
}
